class window.WindowGenerator
  createRoom : (x0, y0, x1, y1) ->
    for x in [x0..x1]
      @tiles.makeWall x, y0
      @tiles.makeWall x, y1 

    for y in [y0..y1]
      @tiles.makeWall x0, y
      @tiles.makeWall x1, y

  createCells : (x0, y0, x1, y1) ->
    @tiles.fillTilesIfNotThere x0, y0, x1 - x0, y1 - y0, [0, 496]
    @createRoom x0, y0, x1, y1
    dx = x1 - x0 #Cell is 2 x 2 + 1

    left = dx - 1

    rooms = []
    corridorPostions = []

    xCells = (left / 3) | 0
    corridorPostions.push [x1 - 2, y0 + 1, x1 - 2, y1 - 1]


    for x in [0..xCells - 1]
      @createRoom x0 + x * 3, y0, x0 + x * 3 + 3, y0 + 3
      @tiles.createDoorTile x0 + x * 3 + 1, y0 + 3
      r = [x0 + x * 3 + 1, y0 + 1, x0 + x * 3 + 3, y0 + 3]
      rooms.push r
      @tiles.fillTilesIfNotThere r[0], r[1], r[2] - r[0], r[3] - r[1], [0, 480]
    
    corridorPostions.push [x0 + 2, y0 + 4, x1 - 2, y0 + 5]

    yy = y0 + 6
    while yy + 3 < y1 - 2
      for x in [0..xCells - 1]
        r = [x0 + x * 3 + 1, yy + 1, x0 + x * 3 + 3, yy + 3]
        rooms.push r
        @tiles.fillTilesIfNotThere r[0], r[1], r[2] - r[0], r[3] - r[1], [0, 480]
        
        @createRoom x0 + x * 3, yy, x0 + x * 3 + 3, yy + 3
        @tiles.createDoorTile x0 + x * 3 + 1, yy

      yy += 3
      for x in [0..xCells - 1]
        @createRoom x0 + x * 3, yy, x0 + x * 3 + 3, yy + 3
        r = [x0 + x * 3 + 1, yy + 1, x0 + x * 3 + 3, yy + 3]
        rooms.push r
        @tiles.fillTilesIfNotThere r[0], r[1], r[2] - r[0], r[3] - r[1], [0, 480]
        @tiles.createDoorTile x0 + x * 3 + 1, yy + 3

      corridorPostions.push [x0 + 2, yy + 4, x1 - 2, yy + 5]
      yy += 6
    

    return [rooms, corridorPostions]
  eqCell : (a, b) ->
    return a[0] == b[0] and a[1] == b[1] and a[2] == b[2] and a[3] == b[3]
  generateWorld : (@game, @tiles) ->
    x = 0
    y = 0
    w = 12 + (Math.random() * 3 | 0) * 3
    h = 15 + (Math.random() * 2 | 0) * 8 + 1

    [cells, cellsCorridors] = @createCells x, y, x + w, y + h
    
    plCell = window.rnd.choose cells
    [sx, sy] = window.rnd.rndCell plCell
    e = @game.addEntity new window.Player()
    e.x = sx * 64
    e.y = sy * 64

    for c in cellsCorridors
      [sx, sy] = window.rnd.rndCell c

      e = @game.addEntity new window.Guard()
      e.x = sx * 64
      e.y = sy * 64

    for c in cells
      if Math.random() > 0.5
        [sx, sy] = window.rnd.rndCell c
        
        e = @game.addEntity new window.Stone()
        e.x = sx * 64
        e.y = sy * 64

      if Math.random() > 0.9 and not @eqCell plCell, c
        [sx, sy] = window.rnd.rndCell c
        
        e = @game.addEntity new window.CellKey()
        e.x = sx * 64
        e.y = sy * 64      


      if Math.random() > 0.8
        [sx, sy] = window.rnd.rndCell c
        
        e = @game.addEntity new window.Bottle()
        e.x = sx * 64
        e.y = sy * 64



    y += h + 2

    nx = Math.random() * w * 0.5 | 0
    nw = 12 + (Math.random() * 4 | 0) * 4
    
    xx0 = x + w
    xx1 = nx + nw

    mx0 = Math.max(nx, x)
    mx1 = Math.min(xx0, xx1)

    rw = (mx1 - mx0 - 2) * Math.random() | 0

    @tiles.fillTilesIfNotThere nx, y - 2, 2, 2, [16, 480]
    @createRoom nx, y - 2, nx + 2, y
    @createOpenDoorTile nx + 1, y - 2
    @createOpenDoorTile nx + 1, y
    x = nx
    w = nw
    h = 15 + (Math.random() * 3 | 0) * 3 + 2

    [tables, diningCorridors] = @createDining x, y, x + w, y + h
    
    for table in tables
        for i in [0..3]
          if Math.random() > 0.5
            [sx, sy] = window.rnd.rndCell table
            e = @game.addEntity new window.Plate()
            e.x = sx * 64
            e.y = sy * 64

    for c in diningCorridors
      [sx, sy] = window.rnd.rndCell c

      e = @game.addEntity new window.Guard()
      e.x = sx * 64
      e.y = sy * 64

    y += h + 2

    @createCourtYard x - 5, y, x + w + 5, y + 10

    cx = x + w / 2
    @tiles.fillTilesIfNotThere cx - 1, y - 2, 2, 2, [16, 480]
    @createRoom cx - 1, y - 2, cx + 1, y 
    @createOpenDoorTile cx, y
    @createOpenDoorTile cx, y - 2
    
    

    #utility item
    [sx, sy] = window.rnd.rndCell plCell
    e = @game.addEntity new window.Stone()
    e.x = sx * 64
    e.y = sy * 64

    #cell key
    [sx, sy] = window.rnd.rndCell plCell
    e = @game.addEntity new window.CellKey()
    e.x = sx * 64
    e.y = sy * 64

  createOpenDoorTile : (x, y) ->
    @tiles.createDoorTile x, y
    door = @tiles.getTile x, y    
    door.locked = false
    door.open = true
    door.doorSpr = door.openSpr

  createDining : (x0, y0, x1, y1) ->
    # Big room with rows of tables
    @tiles.fillTilesIfNotThere x0, y0, x1 - x0, y1 - y0, [16, 480]
    @createRoom x0, y0, x1, y1
    @createRoom x0 + 3, y0 + 3, x1, y1 - 3

    winner = (x1 - 3) - (x0 + 3)
    hinner = (x1 - 3) - (x0 + 3)

    tables = []
    corridors = []
    
    cx = (x0 + x1) / 2
    cy = (y0 + y1) / 2

    corridors.push [x0 + 1, y0 + 1, x0 + 2, y1 - 1]
    corridors.push [x0 + 1, y0 + 1, x1 - 1, y0 + 2]
    corridors.push [x0 + 1, y1 - 2, x1 - 1, y1 - 1]

    @tiles.fillTilesIfNotThere x0 + 3, y0 + 3, x1 - x0 - 3, y1 - y0 - 6, [32, 480]
    @createOpenDoorTile cx,  y0 + 3
    @createOpenDoorTile cx,  y1 - 3
    @createOpenDoorTile x0 + 3,  cy

    for y in [y0 + 5..y1 - 5] by 3
      for x in [x0 + 5..cx - 2]
        @tiles.createTableTile x, y

      tables.push [x0 + 5, y, cx - 2, y + 1]

      for x in [cx + 2..x1 - 2]
        @tiles.createTableTile x, y

      tables.push [cx + 2, y, x1 - 2, y + 1]

    return [tables, corridors]

  createCourtYard : (x0, y0, x1, y1) ->
    w = x1 - x0
    h = y1 - y0

    @tiles.fillTilesIfNotThere x0, y0, w, h, [0, 464]
    @tiles.fillTilesIfNotThere x0 - 3, y0, 3, h, [16, 496]
    @tiles.fillTilesIfNotThere x1, y0, 3, h, [16, 496]
    @tiles.fillTilesIfNotThere x0 - 3, y1, w + 3, 3, [16, 496]

    for x in [x0..x1]
      @tiles.makeWall x, y0

    for x in [x0+1..x1-1]
      @tiles.makeFence x, y1 - 1

    for y in [y0 + 1..y1 - 1]
      @tiles.makeFence x0 + 1, y
      @tiles.makeFence x1 - 1, y

    xe = x0 + (w - 2) * Math.random() | 0
    @tiles.makeExitTile xe, y1 - 1